// 🔒 网络重连管理器 - 核心离线功能，修改需审批

import { ElMessage, ElNotification } from 'element-plus'

import { pphService } from '../services/pphService'

export interface OfflineRecord {
  id: string;
  data: any;
  timestamp: string;
  retryCount: number;
  syncStatus: 'pending' | 'syncing' | 'synced' | 'failed';
}

export class ReconnectManager {
  private isOnline: boolean = navigator.onLine;
  private reconnectTimer: number | null = null;
  private healthCheckTimer: number | null = null;
  private retryCount: number = 0;
  private maxRetries: number = 5;
  private retryInterval: number = 3000; // 3秒
  private healthCheckInterval: number = 10000; // 10秒

  // 离线数据存储
  private readonly OFFLINE_STORAGE_KEY = 'pph_offline_records';
  private readonly MAX_OFFLINE_RECORDS = 1000;

  constructor() {
    this.initializeEventListeners();
    this.startHealthCheck();
  }

  private initializeEventListeners(): void {
    // 浏览器网络事件
    window.addEventListener('online', this.handleOnline.bind(this));
    window.addEventListener('offline', this.handleOffline.bind(this));
    
    // 自定义网络错误事件
    window.addEventListener('network-error', this.handleNetworkError.bind(this));
    
    // 页面可见性变化
    document.addEventListener('visibilitychange', this.handleVisibilityChange.bind(this));
  }

  private handleOnline(): void {
    this.updateNetworkStatus(true);
  }

  private handleOffline(): void {
    console.warn('📡 浏览器检测到网络断开');
    this.updateNetworkStatus(false);
  }

  private handleNetworkError(): void {
    console.warn('🚫 API请求失败，可能网络中断');
    this.updateNetworkStatus(false);
  }

  private handleVisibilityChange(): void {
    if (!document.hidden && this.isOnline) {
      // 页面重新可见时检查连接
      this.checkServerConnection();
    }
  }

  private updateNetworkStatus(online: boolean): void {
    const wasOffline = !this.isOnline;
    this.isOnline = online;

    if (online && wasOffline) {
      this.retryCount = 0;
      this.showNotification('网络已恢复', '正在同步离线数据...', 'success');
      this.syncOfflineData();
    } else if (!online) {
      this.showNotification('网络连接中断', '数据将保存到本地缓存', 'warning');
      this.startReconnectAttempts();
    }

    // 触发全局网络状态更新
    window.dispatchEvent(new CustomEvent('network-status-change', { 
      detail: { isOnline: online } 
    }));
  }

  private startHealthCheck(): void {
    this.healthCheckTimer = window.setInterval(async () => {
      if (this.isOnline) {
        const serverOnline = await this.checkServerConnection();
        if (!serverOnline) {
          this.updateNetworkStatus(false);
        }
      }
    }, this.healthCheckInterval);
  }

  private async checkServerConnection(): Promise<boolean> {
    try {
      return await pphService.healthCheck();
    } catch {
      return false;
    }
  }

  private startReconnectAttempts(): void {
    if (this.reconnectTimer) {
      clearInterval(this.reconnectTimer);
    }

    this.reconnectTimer = window.setInterval(async () => {
      if (this.retryCount >= this.maxRetries) {
        this.stopReconnectAttempts();
        this.showNotification(
          '重连失败', 
          '已达最大重试次数，请检查网络设置', 
          'error'
        );
        return;
      }

      this.retryCount++;
      console.log(`🔄 重连尝试 ${this.retryCount}/${this.maxRetries}...`);

      const connected = await this.checkServerConnection();
      if (connected) {
        this.updateNetworkStatus(true);
        this.stopReconnectAttempts();
      }
    }, this.retryInterval);
  }

  private stopReconnectAttempts(): void {
    if (this.reconnectTimer) {
      clearInterval(this.reconnectTimer);
      this.reconnectTimer = null;
    }
  }

  // 离线数据管理
  public saveOfflineRecord(record: any): void {
    try {
      const offlineRecords = this.getOfflineRecords();
      
      // 检查存储限制
      if (offlineRecords.length >= this.MAX_OFFLINE_RECORDS) {
        // 删除最旧的记录
        offlineRecords.shift();
        console.warn('⚠️ 离线记录已达上限，删除最旧记录');
      }

      const offlineRecord: OfflineRecord = {
        id: this.generateId(),
        data: record,
        timestamp: new Date().toISOString(),
        retryCount: 0,
        syncStatus: 'pending'
      };

      offlineRecords.push(offlineRecord);
      localStorage.setItem(this.OFFLINE_STORAGE_KEY, JSON.stringify(offlineRecords));
      
      } catch (error) {
      console.error('❌ 离线记录保存失败:', error);
      ElMessage.error('离线数据保存失败');
    }
  }

  public getOfflineRecords(): OfflineRecord[] {
    try {
      const data = localStorage.getItem(this.OFFLINE_STORAGE_KEY);
      return data ? JSON.parse(data) : [];
    } catch {
      return [];
    }
  }

  public getOfflineRecordCount(): number {
    return this.getOfflineRecords().length;
  }

  private async syncOfflineData(): Promise<void> {
    const offlineRecords = this.getOfflineRecords();
    if (offlineRecords.length === 0) return;

    try {
      // 标记为同步中
      const updatedRecords = offlineRecords.map(record => ({
        ...record,
        syncStatus: 'syncing' as const
      }));
      localStorage.setItem(this.OFFLINE_STORAGE_KEY, JSON.stringify(updatedRecords));

      // 提取数据进行同步
      const recordsData = offlineRecords.map(record => record.data);
      const result = await pphService.syncOfflineRecords(recordsData);

      // 清除已同步的记录
      this.clearOfflineRecords();
      
      this.showNotification(
        '数据同步完成', 
        `成功同步 ${result.synced} 条记录`, 
        'success'
      );

    } catch (error) {
      console.error('❌ 离线数据同步失败:', error);
      
      // 恢复为待同步状态
      const failedRecords = offlineRecords.map(record => ({
        ...record,
        syncStatus: 'failed' as const,
        retryCount: record.retryCount + 1
      }));
      localStorage.setItem(this.OFFLINE_STORAGE_KEY, JSON.stringify(failedRecords));
      
      ElMessage.error('离线数据同步失败，将在下次网络恢复时重试');
    }
  }

  private clearOfflineRecords(): void {
    localStorage.removeItem(this.OFFLINE_STORAGE_KEY);
  }

  private generateId(): string {
    return Date.now().toString(36) + Math.random().toString(36).substr(2);
  }

  private showNotification(title: string, message: string, type: 'success' | 'warning' | 'error' | 'info' = 'info'): void {
    ElNotification({
      title,
      message,
      type,
      duration: type === 'error' ? 0 : 4500,
      position: 'top-right'
    });
  }

  // 公共方法
  public getNetworkStatus(): { isOnline: boolean; retryCount: number; canRetry: boolean } {
    return {
      isOnline: this.isOnline,
      retryCount: this.retryCount,
      canRetry: this.retryCount < this.maxRetries
    };
  }

  public async manualReconnect(): Promise<boolean> {
    const connected = await this.checkServerConnection();
    
    if (connected) {
      this.updateNetworkStatus(true);
      return true;
    } else {
      ElMessage.error('重连失败，请检查网络连接');
      return false;
    }
  }

  public destroy(): void {
    if (this.reconnectTimer) {
      clearInterval(this.reconnectTimer);
    }
    if (this.healthCheckTimer) {
      clearInterval(this.healthCheckTimer);
    }
    
    window.removeEventListener('online', this.handleOnline);
    window.removeEventListener('offline', this.handleOffline);
    window.removeEventListener('network-error', this.handleNetworkError);
    document.removeEventListener('visibilitychange', this.handleVisibilityChange);
  }
}

// 导出单例实例
export const reconnectManager = new ReconnectManager();
export default reconnectManager;
